package jo.co.yui.alogcatviewer;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultStyledDocument;
import javax.swing.text.Document;
import javax.swing.text.StyleContext;
import javax.swing.text.Utilities;

/**
 * A class illustrating running line number count on JTextPane. Nothing is
 * painted on the pane itself, but a separate JPanel handles painting the line
 * numbers.<br>
 * 
 * @author Daniel Sjöblom<br>
 *         Created on Mar 3, 2004<br>
 *         Copyright (c) 2004<br>
 * @version 1.0<br>
 */
public class MyPanel extends JPanel {
	private static final long serialVersionUID = 1L;
	private static StyleContext sc = new StyleContext();
	private static DefaultStyledDocument doc = new DefaultStyledDocument(sc);
	// for this simple experiment, we keep the pane + scrollpane as members.
	JTextPane pane;
	JScrollPane scrollPane;

	public MyPanel(DefaultStyledDocument doc) {
		super();
		setMinimumSize(new Dimension(30, 30));
		setPreferredSize(new Dimension(30, 30));
		setMinimumSize(new Dimension(30, 30));
		pane = new JTextPane(doc) // we need to override paint so that
									// thelinenumbers stay in sync
		{
			public void paint(Graphics g) {
				super.paint(g);
				MyPanel.this.repaint();
			}
		};

		scrollPane = new JScrollPane(pane);

	}

	public JTextPane getPane() {
		return pane;
	}

	public void setPane(JTextPane pane) {
		this.pane = pane;
	}

	public JScrollPane getScrollPane() {
		return scrollPane;
	}

	public void setScrollPane(JScrollPane scrollPane) {
		this.scrollPane = scrollPane;
	}

	public DefaultStyledDocument getDoc() {
		return doc;
	}

	public void setDoc(DefaultStyledDocument doc) {
		this.doc = doc;
	}

	public void paint(Graphics g) {
		super.paint(g);

		// We need to properly convert the points to match the viewport
		// Read docs for viewport
		int start = pane
				.viewToModel(scrollPane.getViewport().getViewPosition()); // starting
																			// pos
																			// in
																			// document
		int end = pane.viewToModel(new Point(scrollPane.getViewport()
				.getViewPosition().x + pane.getWidth(), scrollPane
				.getViewport().getViewPosition().y + pane.getHeight()));
		// end pos in doc

		// translate offsets to lines
		Document doc = pane.getDocument();
		int startline = doc.getDefaultRootElement().getElementIndex(start);
		int endline = doc.getDefaultRootElement().getElementIndex(end);

		int fontHeight = g.getFontMetrics(pane.getFont()).getHeight(); // fontheight

		String strLine = "";
		for (int line = startline, y = 0; line <= endline; line++, y += fontHeight ) {
			if (line == 0)
				strLine = "";
			else
				strLine = Integer.toString(line);
//			g.drawString(strLine, 10, y );
		}

	}

	/**
	 * Return an int containing the wrapped line index at the given position
	 * 
	 * @param component
	 *            JTextPane
	 * @param int pos
	 * @return int
	 */
	public static int getLineNumber(JTextPane component, int pos) {
		int posLine;
		int y = 0;

		try {
			Rectangle caretCoords = component.modelToView(pos);
			y = (int) caretCoords.getY();
		} catch (BadLocationException ex) {
		}

		int lineHeight = component.getFontMetrics(component.getFont())
				.getHeight();
		posLine = (y / lineHeight) + 1;
		return posLine;
	}
	 public static int getColNumber(JTextPane component, int pos) {
	        try {
	            return pos-Utilities.getRowStart(component, pos)+1;
	        } catch (BadLocationException e) {
	            e.printStackTrace();
	        }
	        return -1;
	    }
	// test main
	public static void main(String[] args) {
		JFrame frame = new JFrame();
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.getContentPane().setLayout(new BorderLayout());
		final MyPanel nr = new MyPanel(null);
		frame.getContentPane().add(nr, BorderLayout.WEST);
		frame.getContentPane().add(nr.scrollPane, BorderLayout.CENTER);
		frame.pack();
		frame.setSize(new Dimension(400, 400));
		frame.show();
	}
}